package com.gome.ocean.service.elasticsearch.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.count.CountResponse;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.SearchType;
import org.elasticsearch.client.Client;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.elasticsearch.index.query.WildcardQueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.stereotype.Service;

import com.gome.ocean.service.elasticsearch.IElasticSearchService;
import com.gome.ocean.service.utils.HttpClientEsUtil;
import com.taobao.tddl.common.utils.logger.Logger;
import com.taobao.tddl.common.utils.logger.LoggerFactory;

/**
 * @author zhangguoqing 2016年8月2日 下午5:45:25
 * @since 5.0.0
 */
@Service("elasticSearchService")
public class ElasticSearchServiceImpl implements IElasticSearchService {

    private static final Logger LOG = LoggerFactory.getLogger(ElasticSearchServiceImpl.class);
    private static Client       client;

    /*
     * static { client = HttpClientEsUtil.getClient(); }
     */

    @Override
    public List<Map<String, Object>> queryListMapByFilterType(String environValue, String indexName,
                                                              String typeName, String tableName, String fieldName,
                                                              String fieldValue, String userEmail, String startTime,
                                                              String endTime, int startSize, int endSize) {
        try {
            SearchRequestBuilder reqBuilder = client.prepareSearch(indexName)
                .setTypes(typeName)
                .setSearchType(SearchType.DEFAULT)
                .setExplain(true);
            BoolQueryBuilder builder = new BoolQueryBuilder();
            if (StringUtils.isNotEmpty(tableName)) {
                WildcardQueryBuilder wild = QueryBuilders.wildcardQuery("searchSql", "*" + tableName + "*");
                builder.must(wild);
            }
            if (StringUtils.isNotEmpty(userEmail)) {
                MatchQueryBuilder match = QueryBuilders.matchQuery("searchUser", userEmail);
                builder.must(match);
            }
            if (StringUtils.isNotEmpty(environValue)) {
                MatchQueryBuilder match = QueryBuilders.matchQuery("environValue", environValue);
                builder.must(match);
            }
            if (StringUtils.isNotEmpty(fieldName)) {
                WildcardQueryBuilder wild1 = QueryBuilders.wildcardQuery("result", "*" + fieldName + "*");
                builder.must(wild1);
            }
            if (StringUtils.isNotEmpty(fieldValue)) {
                WildcardQueryBuilder wild2 = QueryBuilders.wildcardQuery("result", "*" + fieldValue + "*");
                builder.must(wild2);
            }
            if (StringUtils.isNotEmpty(startTime) && StringUtils.isNotEmpty(endTime)) {
                RangeQueryBuilder range = QueryBuilders.rangeQuery("searchTime")
                    .from(startTime)
                    .to(endTime)
                    .includeLower(true)
                    .includeUpper(false);
                builder.must(range);
            }
            CountResponse countResponse = client.prepareCount(indexName)
                .setTypes(typeName)
                .setQuery(builder)
                .execute()
                .actionGet();
            Long totalCount = countResponse.getCount();
            int pageNum = startSize;
            if (pageNum == 1) {
                startSize = 0;
                endSize = 10;
            } else {
                startSize = (startSize - 1) * 10;
                endSize = pageNum * 10;
            }
            reqBuilder.setQuery(builder)
                .addSort("searchTime", SortOrder.DESC)
                .setFrom(startSize)
                .setSize(endSize)
                .setExplain(true);
            SearchResponse response = reqBuilder.execute().actionGet();
            SearchHit[] hits = response.getHits().getHits();
            List<Map<String, Object>> results = new ArrayList<Map<String, Object>>();
            Map<String, Object> map = new HashMap<String, Object>();
            if (hits != null && hits.length > 0) {
                for (SearchHit hit : hits) {
                    results.add(hit.getSource());
                }
                map.put("totalPage", totalCount);
                results.add(map);
            }
            return results;
        } catch (Exception e) {
            LOG.error(e.toString());
            return null;
        }
    }

}
